package com.xudm.cdg.service;

import cn.hutool.crypto.digest.MD5;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.databind.JsonNode;
import com.xudm.cdg.api.MoonShotApi;
import com.xudm.cdg.api.TyqwApi;
import com.xudm.cdg.entity.cosmic.DataDict;
import com.xudm.cdg.utils.JsonUtil;
import com.xudm.cdg.utils.MarkdownUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 数据字典服务
 *
 * @author xudm
 */
@Service
@Slf4j
public class DataDictService {

    @Resource
    private TyqwApi qwApi;

    @Resource
    private MoonShotApi moonShotApi;

    @Resource
    private RedisService redisService;

    private final MD5 md5 = MD5.create();
    // 提示信息
    public static final String JOSN_IMG_PROMPT = "你会接受一串由顿号或逗号分隔的文本，将其分割、翻译成英文，多个单词使用小驼峰或者下划线来连接，并将其视为一个变量。然后根据该变量提供合适的案例值，并组装成一个单层 JSON 对象。JSON 对象中变量名只能使用英文，而案例值可以使用中文。" +
            "例如你收到\"节点查询状态，人员配置查询状态，投诉工单节点明细信息，水果名称\"\n最终输出的 JSON 对象示例：\n{\n\"node_query_status\": \"成功\",\n\"staffing_query_status\":\"成功状态\",\n\"complaint_work_order_node_details\":\"投诉工单节点明细信息xxxxxx\",\n\"fruit_name\":\"苹果,香蕉,橙子\"\n}\n注意事项：输出的json对象中不能包含注释。json对象只能单层，不能嵌套对象";
    public static final String DICT_TABLE_PROMPT = "你将收到一段用逗号或者顿号分隔的文本，你需要做的是把这些文本分割以后的词汇翻译成英文，多个单词使用小驼峰连接，然后给出变量如果作为mysql数据库表的字段，应该要用什么数据类型、长度、非空等，非空以0或者1表示，并以markdown表格的形式输出，表头为字段名、别名、类型、长度、非空，只返回markdown格式的表格，不需要多余的描述。";

    public String getDict(String maketdownStr) {
        List<String> dictList = new ArrayList<>();
        // 正则表达式匹配Markdown表格的行
//        String regex = "\\|.*?\\|";
        String result = "";
        String regex = "(\\|.*?\\|\\n)+";
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(maketdownStr);
        // 查找所有匹配的行并打印
        while (matcher.find()) {
            result = matcher.group();
        }
        return result;
    }

    public List<DataDict> getDictList(String question) {
        String digestHex = "DICT_TABLE_" + md5.digestHex(question);
        String object = redisService.get(digestHex, String.class);
        String result = "";
        if (object != null) {
            result = object;
        } else {
            JSONObject jsonObject = qwApi.chatByQw(question, DICT_TABLE_PROMPT);
//            JSONObject jsonObject = moonShotApi.singleChat(question, DICT_TABLE_PROMPT);
            JSONArray jsonArray = jsonObject.getJSONObject("output").getJSONArray("choices");
//            JSONArray jsonArray = jsonObject.getJSONArray("choices");
            JSONObject json = (JSONObject) jsonArray.get(0);
            result = json.getJSONObject("message").getString("content");
            redisService.set(digestHex, result);
        }
        String dict = "";
        if (result.startsWith("|") && result.endsWith("|")) {
            dict = result;
        } else {
            dict = getDict(result + "\n\n");
        }
        String[][] stringArrays = MarkdownUtil.parseMarkdownTable(dict);

        int length = stringArrays.length;
        List<DataDict> dictList = new ArrayList<>();
        if (length > 2) {
            for (int i = 2; i < length; i++) {
                String[] strings = stringArrays[i];
                dictList.add(new DataDict(strings[0], strings[1], strings[2], strings[3], strings[4], ""));
            }
        } else {
            log.error("数据字典解析失败,请检查数据字典格式是否正确,{}", digestHex);
        }
        return dictList;
    }

    /**
     * 获取数据字典的json图片
     *
     * @param question 问题
     * @return
     */
    public InputStream getDataDictJsonImg(String question) {
        String digestHex = "JSON_IMG_" + md5.digestHex(question);
        try {
            String object = redisService.get(digestHex, String.class);
            String result = "";
            if (object != null) {
                result = object;
            } else {
                JSONObject jsonObject = qwApi.chatByQw(question, JOSN_IMG_PROMPT);
//                JSONObject jsonObject = moonShotApi.singleChat(question, JOSN_IMG_PROMPT);
                JSONArray jsonArray = jsonObject.getJSONObject("output").getJSONArray("choices");
//                JSONArray jsonArray = jsonObject.getJSONArray("choices");
                JSONObject json = (JSONObject) jsonArray.get(0);
                result = json.getJSONObject("message").getString("content");
                redisService.set(digestHex, result);
            }
            String jsonText = result;
            if (result.contains("```json") && result.contains("```")) {
                jsonText = MarkdownUtil.extractJsonFromMarkdown(result);
            }
            JSONObject jsonObject = JSON.parseObject(jsonText);
            boolean containsChinese = jsonObject.keySet().stream().anyMatch(MarkdownUtil::containsChinese);
            if (containsChinese) {
                log.error("JSON data contains Chinese characters.{},{}", digestHex, question);
                return null;
            }
            // 从markdown中提取的json字符串
            if (jsonText != null) {
                try {
                    JsonNode jsonData = null;
                    jsonData = MarkdownUtil.parseJson(jsonText);
                    String jsonString = jsonData.toPrettyString();
//                    BufferedImage image = MarkdownUtil.renderJsonToImage(jsonString);
                    BufferedImage image = JsonUtil.jsonToImg(jsonString);
                    return MarkdownUtil.convertBufferedImageToInputStream(image, "png");
                } catch (Exception e) {
                    log.error("Failed to render JSON to image digestHex.{},{}", digestHex, question);
                    log.error("Failed to render JSON to image.", e);
                }
            } else {
                log.info("No JSON data found in the Markdown text.{}", question);
            }
            return null;
        } catch (Exception e) {
            log.error("Failed to render JSON to image.{},{}", digestHex, question);
            log.error("Failed to render JSON to image.", e);
        }
        return null;
    }
}
